package org.eclipse.wtp.puzzled;

import java.util.*;

public class Sudoku {
	private SudokuGenerator sg = new SudokuGenerator(3);
	private int level;
	public int[][] answers = new int[9][9];
	public int[][] myGrid = new int[9][9];
	public boolean[][] userInput = new boolean[9][9];	
	public boolean[][] correct = new boolean[9][9];
	public boolean[][] hints = new boolean[9][9];
	//Constructor
	public Sudoku(int level) {
		//Level of difficulty
		this.level = level;
		//Generate the sudoku puzzle
		sg.generate(false);
		//get the answers
		answers = sg.getGrid();
		Random r = new Random();
		//The number of blank cells for the sudoku puzzle depends on the level
		int empties = 15;
		empties += level*10;
		int i,j;
		//Initialize board
		for (i=0; i<9; i++) {
			for (j=0; j<9; j++) {
				myGrid[i][j] = answers[i][j];
				userInput[i][j] = false;
				correct[i][j] = false;
				hints[i][j] = false;
			}
		}
		int x,y;
		// locate the empty cells and set them to -1 for us to know they are empty
		for (i=0; i<empties; i++) {
			x = Math.abs(r.nextInt(9));
			y = Math.abs(r.nextInt(9));
			while (myGrid[x][y] == -1) {
				x = Math.abs(r.nextInt(9));
				y = Math.abs(r.nextInt(9));
			}
			myGrid[x][y] = -1;
			// We will know that a User can use this cell.
			userInput[x][y] = true;
		}
	}
	// Solve the puzzle
	public void solve() {
		int i,j;
		for (i=0; i<9; i++) {
			for (j=0; j<9; j++) {
				// if that location is already correct then just set it to correct
				if (myGrid[i][j] == answers[i][j])
					correct[i][j] = true;
				else{// else set that location to correct
					myGrid[i][j] = answers[i][j];
				}
			}
		}
	}
	//Gives the player a hint. It first shows an empty cell and then chooses
	// a players cell that has already been filled in but incorrect.
	public void hint() {
		int i,j;
		Random r = new Random();
		i = Math.abs(r.nextInt(9));
		j = Math.abs(r.nextInt(9));
		while (!isUserInput(i,j) || isHint(i,j) || (!cellEmpty(i,j) && (numEmpties() > 0))) {
			i = Math.abs(r.nextInt(9));
			j = Math.abs(r.nextInt(9));
		}
		myGrid[i][j] = answers[i][j];
		hints[i][j] = true;
		userInput[i][j] = false;
	}
	// Returns the amount of hints that the player has chosen. 
	public int numHints() {
		int i,j,total=0;
		for (i=0; i<9; i++) {
			for (j=0; j<9; j++) {
				if (hints[i][j])
					total++;
			}
		}
		return total;
	}
	// Returns the number of user inputs in the grid
	public int numUserInput() {
		int i,j,total=0;
		for (i=0; i<9; i++) {
			for (j=0; j<9; j++) {
				if (userInput[i][j])
					total++;
			}
		}
		return total;
	}
	//Returns the number of user inputs initial
	public int numOrigUserInput() {
		int empties = 15;
		empties += level*10;
		return empties;
	}
	//Returns the number of correct cells the user has input. 
	public int numCorrect() {
		int i,j,total=0;
		for (i=0; i<9; i++) {
			for (j=0; j<9; j++) {
				if (correct[i][j] && userInput[i][j]) {
					//System.out.println("X:"+i+" Y:"+j+" is correct");
					total++;
				}
			}
		}
		return total;
	}
	//Returns the number in each cell.
	public String getCell(int x, int y) {
		if (myGrid[x][y] != -1)
			return Integer.toHexString((myGrid[x][y])).toUpperCase();
		else// A blank cell waiting for user input. 
			return "";
	}
	//Allows the cell to be incremented.
	public void selectCell(int x, int y) {
		if (myGrid[x][y] == -1)
			myGrid[x][y] = 1;
		else if (myGrid[x][y] == 9)
			myGrid[x][y] = -1;
		else
			myGrid[x][y]++;
	}
	//Returns if the cell is empty waiting for user input.
	public boolean cellEmpty(int x, int y) {
		return (myGrid[x][y] == -1);
	}
	// Returns if the user input was correct.
	public boolean isCorrect(int x, int y) {
		return correct[x][y];
	}
	// Returns if the cell was a hint or not.
	public boolean isHint(int x, int y) {
		return hints[x][y];
	}
	//Returns if the cell is a user input cell AKA empty at start.
	public boolean isUserInput(int x, int y) {
		return userInput[x][y];
	}
	// Returns the number of empty cells.
	public int numEmpties() {
		int i,j,total=0;
		for (i=0; i<9; i++) {
			for (j=0; j<9; j++) {
				if (cellEmpty(i,j))
					total++;
			}
		}
		return total;
	}
	// Shows the cell to the user.
	public void showCell(int x, int y) {
		if (myGrid[x][y] == -1){
			myGrid[x][y] = answers[x][y];
			correct[x][y]= true;
		}
	}
}
